package net.gxtvsgwt.client.app.view;

import java.util.ArrayList;
import java.util.List;

import net.gxtvsgwt.client.Gxtvsgwt;
import net.gxtvsgwt.client.app.AppPresenter;
import net.gxtvsgwt.client.demo.Demo;

import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.inject.Inject;

public class AppViewImpl extends Composite implements AppView {

	private static AppViewImplUiBinder uiBinder = GWT
			.create(AppViewImplUiBinder.class);

	interface AppViewImplUiBinder extends UiBinder<Widget, AppViewImpl> {
	}

	@UiField
	ListBox widgetTypeList;

	@UiField
	TextBox dataSizeText;

	@UiField
	Button runButton;

	@UiField
	HTML sourceLink;

	@UiField
	FlowPanel resultPanel;

	@UiField
	Label gxtVersion;

	@UiField
	Label gwtVersion;

	@UiField
	Label userAgent;

	@UiField
	Label resultWidgetType;

	@UiField
	Label resultDataSize;

	@UiField
	Label gxtRenderTime;

	@UiField
	Label gwtRenderTime;

	@UiField
	HTML message;

	@Inject
	private AppPresenter presenter;

	private List<PopupPanel> popups = new ArrayList<PopupPanel>();

	private int lastHeight;

	public AppViewImpl() {
		initWidget(uiBinder.createAndBindUi(this));
		Scheduler.get().scheduleDeferred(new ScheduledCommand() {
			@Override
			public void execute() {
				onTypeChange(null);
			}
		});
	}

	@Override
	public int getSelectedIndex() {
		return widgetTypeList.getSelectedIndex();
	}

	@Override
	public int getDataSize() {
		try {
			return Integer.valueOf(dataSizeText.getText());
		} catch (Exception e) {
			return 0;
		}
	}

	@Override
	public void setTypes(List<String> types) {
		for (String type : types) {
			widgetTypeList.addItem(type);
		}
	}

	@Override
	public void setMessage(String message) {
		this.message.setHTML(message);
	}

	@Override
	public long showDemo(Demo demo, boolean gxt) {
		final PopupPanel popup = new PopupPanel();
		popup.center();
		int left = 20;
		int top = 400;
		if (!gxt) {
			top += lastHeight + 30;
		}
		popup.setPopupPosition(Math.max(Window.getScrollLeft() + left, 0),
				Math.max(Window.getScrollTop() + top, 0));
		popups.add(popup);
		FlowPanel fp = new FlowPanel();
		fp.add(new Label(gxt ? "GXT" : "GWT"));
		popup.add(fp);
		long start = System.currentTimeMillis();
		fp.add(gxt ? demo.createGxt() : demo.createGwt());
		long time = System.currentTimeMillis() - start;
		lastHeight = fp.getOffsetHeight();
		return time;
	}

	@Override
	public void showResult(String widgetType, int dataSize, long gxtDuration,
			long gwtDuration) {
		resultPanel.setVisible(true);
		userAgent.setText(getUserAgent());
		gxtVersion.setText(Gxtvsgwt.GXT_VERSION);
		gwtVersion.setText(Gxtvsgwt.GWT_VERSION);
		resultWidgetType.setText(widgetType);
		resultDataSize.setText(dataSize + "");
		gxtRenderTime.setText(gxtDuration + "ms");
		gwtRenderTime.setText(gwtDuration + "ms");
		if (gxtDuration < 1) {
			gxtDuration = 1;
		}
		if (gwtDuration < 1) {
			gwtDuration = 1;
		}
		if (gxtDuration > gwtDuration) {
			setMessage("GXT was " + (gxtDuration / gwtDuration)
					+ "x <span style=\"color: red\">slower</span>...");
		} else {
			setMessage("GXT was " + (gwtDuration / gxtDuration)
					+ "x <span style=\"color: green\">faster</span>...");
		}
	}

	@Override
	public void reset() {
		for (PopupPanel popup : popups) {
			popup.hide();
		}
		popups.clear();
		resultPanel.setVisible(false);
		setMessage("");
	}

	@UiHandler("runButton")
	void onRunClick(ClickEvent e) {
		presenter.run();
	}

	@UiHandler("widgetTypeList")
	void onTypeChange(ChangeEvent e) {
		sourceLink.setHTML("<a href=\"/src/"
				+ widgetTypeList.getItemText(widgetTypeList.getSelectedIndex())
						.split("-")[0].replace(" ", "")
				+ "Demo.java\" target=\"_new\">View Source</a>");
	}

	private static native String getUserAgent() /*-{
		return navigator.userAgent;
	}-*/;
}
